﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IrisGenerator.Common.DataTypes;
using IrisGenerator.Framework.RuleEngine;
using IrisGenerator.Framework.Messaging;
using IrisGenerator.Framework.Events;


namespace IrisGenerator.Common.Core.Rules
{
    public class TargetRule : RuleBase<Target>, IDbBindableObjectRules
    {

        #region ctor

        public TargetRule(Target obj):base(obj)
        {
            this.LinkedObject.Deleting += new EventHandler<BaseEventArgs<Target>>(LinkedObject_Deleting);
        }

        #endregion

        #region Properties' Rules

        private bool TarIdIsValid(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            //Rule 1: The Target Id has to have a value to be validated.
            if (this.LinkedObject.TarId == null || !this.LinkedObject.TarId.HasValue)
            {
                if (returnValue==null)
                    returnValue = new RuleErrorCollection();
                returnValue.Add(new RuleError("Target ID", RuleErrorType.PropertyRule, "An Identifier is mandatory"));
                result = false;
            }

            return result;
        }

        private bool TarCodeIsValid(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            
            if (string.IsNullOrEmpty(this.LinkedObject.TarCode))
            {
                if (returnValue == null)
                    returnValue = new RuleErrorCollection();

                returnValue.Add(new RuleError("TarCode", RuleErrorType.PropertyRule, "Code is mandatory"));
                result = false;
            }

            return result;
        }

        private bool TarDescriptionIsValid(ref RuleErrorCollection returnValue)
        {
            return true;
        }

        #endregion

        #region Persistancy Rules

        #region IDbBindableObjectRules

        public bool CanInsert(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            returnValue = null;

            result= result & !TarIdIsValid(ref returnValue);

            result = result & TarCodeIsValid(ref returnValue);
            result = result & TarDescriptionIsValid(ref returnValue);
            

            if (PrimaryKeyExists())
            {
                if (returnValue == null)
                    returnValue = new RuleErrorCollection();

                returnValue.Add(new RuleError("Target Object Conflict", RuleErrorType.BusinessRule, "The code already exists"));
                result = false;
            }
            
            return (result);

        }

        public bool CanUpdate(ref RuleErrorCollection returnValue)
        {
            bool result = true;

            result = result & TarIdIsValid(ref returnValue);
            result = result & TarCodeIsValid(ref returnValue);
            result = result & TarDescriptionIsValid(ref returnValue);

            return result;
        }

        public bool CanDelete(ref RuleErrorCollection returnValue)
        {
            return TarIdIsValid(ref returnValue);
        }

        private bool PrimaryKeyExists()
        {
            var tmp = Target.Load(this.LinkedObject.TarId);
            return (tmp != null);
        }

        #endregion

        #region Event Handling

        void LinkedObject_Deleting(object sender, BaseEventArgs<Target> e)
        {
            if (e.FireMessage)
            {
                IrisGenerator.Framework.Messaging.Message message=new Message("Are you sure you want to delete the metatype " + e.Argument.TarCode + "?"
                    + Environment.NewLine + "This action will delete all linked elements.","Metatype deletion",
                    MessageButtons.YesNo,MessageIcon.Question,MessageDefaultButton.Button2);
                
                MessageResults result=OnMessageSend(new MessageEventArgs<Target>(e.Argument,message));
                if (result!=MessageResults.Yes)
                {
                    e.Cancel=true;
                    return;
                }
            }
        }

        #endregion

        #endregion


    }
}
